home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_08_11 / 8n11059b < prev    next >
Text File  |  1990-09-25  |  5KB  |  214 lines

  1. /*    Program:            usrsnd
  2.  *
  3.  *    Filename:            listing1.c
  4.  *
  5.  *    Description:        Demonstration program that uses a message
  6.  *                    queue to enable users to send one line messages
  7.  *                    to each other.
  8.  *
  9.  *    Contents:            main(), send_mssg(), recv_mssg(),
  10.  *                    get_msg_queue()
  11.  *
  12.  *    Author/Programmer:    W. J. Freda
  13.  *                    Automated Concepts Inc.
  14.  */
  15. #include <stdio.h>
  16. #include <signal.h>
  17. #include <pwd.h>
  18. #include <sys/types.h>
  19. #include <sys/ipc.h>
  20. #include <sys/msg.h>
  21.  
  22. #define KEY     0x5642412
  23. static struct mssg  {
  24.     long mtype;            /* Message type */
  25.     char mtext[BUFSIZ];        /* Message text */
  26. } Msgbuf;
  27. static int Msqid;            /* Message queue identifier */
  28. static int Firstime=1;
  29.  
  30. /*    MAIN
  31.  *
  32.  *    DESCRIPTION:    Provides a simple menu that ties the
  33.  *                send_msg() and recv_msg() functions
  34.  *                together.
  35.  *
  36.  *    INPUT:        NONE
  37.  *    OUTPUT:        Program termination
  38. */
  39. main()
  40. {
  41.     char *mssg, *recv_mssg();
  42.     char selection[80];
  43.  
  44.     while(1)  {
  45.         printf("\n\n\t1) Send a message to a specific user\n");
  46.         printf("\t2) Receive messages\n");
  47.         printf("\t3) Exit\n");
  48.         printf("\n\t\tEnter selection: ");
  49.  
  50.         gets(selection);
  51.  
  52.         switch(*selection)  {
  53.             case '1':
  54.                 send_mssg();
  55.                 break;
  56.             case '2':
  57.                 if ((mssg=recv_mssg()) == NULL)  
  58.                     printf("\n\nNo messages on queue\n\n");
  59.                 else
  60.                     printf("\n\n%s\n\n",mssg);
  61.                 break;
  62.             case '3':
  63.                 exit(0);
  64.             default:
  65.                 printf("\tInvalid selection.\n\n");
  66.                 break;
  67.         }
  68.     }
  69. }
  70.  
  71.  
  72. /*    SEND_MSSG FUNCTION
  73.  *
  74.  *    DESCRIPTION:    Prompts the user for a username and message
  75.  *                and sends the message to that user via a message
  76.  *                queue.  The user can read the message using
  77.  *                rcv_mssg().
  78.  *
  79.  *    INPUT:        NONE
  80.  *    OUTPUT:        0    If successful
  81.  *                -1    Otherwise
  82. */
  83. send_mssg()
  84. {
  85.     extern int Msqid;            /* Message queue identifier  */
  86.     extern struct mssg Msgbuf;    /* Message structure         */
  87.     extern int errno;
  88.     int msglen;                /* Length of message        */
  89.     char message[BUFSIZ];        /* Message text             */
  90.     char username[20];
  91.     struct passwd *pass, *getpwnam();
  92.  
  93.     if (Firstime)  {
  94.         if ((Msqid=get_msg_queue()) == -1) 
  95.             return(-1);
  96.  
  97.         Firstime=0;
  98.     }
  99.  
  100.     /* Prompt for user name */
  101.     printf("\n\nSend message to which user? ");
  102.     gets(username);
  103.  
  104.     /* Validate username */
  105.     setpwent();
  106.     pass=getpwnam(username);
  107.     endpwent();
  108.  
  109.     if (pass == NULL)  {
  110.         printf("Invalid username.\n\n");
  111.         return(0);
  112.     }
  113.  
  114.     /* Prompt user for a message to send */
  115.     printf("Enter message: ");
  116.     gets(Msgbuf.mtext);
  117.  
  118.     if (*(Msgbuf.mtext) == NULL)  
  119.         /* Nothing to send */
  120.         return(0);
  121.         
  122.     /* Set the message length */
  123.     msglen=strlen(Msgbuf.mtext);
  124.  
  125.     /* Set the message type equal to the userid
  126.      * we want to send the message to.
  127.     */
  128.     Msgbuf.mtype = pass->pw_uid;
  129.  
  130.     /* Send the message.  The IPC_NOWAIT flag informs msgsnd()
  131.      * not to send the message if the message queue is full.
  132.      * Without the IPC_NOWAIT flag this process would be put
  133.      * to sleep by the kernel until the message can be sent.
  134.     */
  135.     if (msgsnd(Msqid, &Msgbuf, msglen, IPC_NOWAIT) == -1)  {
  136.         /* Error occurred */
  137.         return(-1);
  138.     }
  139.  
  140.     return(0);
  141. }
  142.  
  143.  
  144. /*    RECV_MSSG FUNCTION        char *recv_mssg()
  145.  *
  146.  *    DESCRIPTION:    Attempts to retrieve a message from the 
  147.  *                message queue.
  148.  *
  149.  *    INPUT:        NONE
  150.  *    OUTPUT:        text    Returns a pointer to the first 
  151.  *                    character of the message text.
  152.  *                NULL    If there are no messages or an 
  153.  *                    error occurred.
  154. */
  155. char *recv_mssg()
  156. {
  157.     extern int Msqid;            /* Message queue identifier  */
  158.     extern struct mssg Msgbuf;    /* Message structure         */
  159.     extern int Firstime;
  160.     int uid;                    /* User id                   */
  161.     int len;
  162.  
  163.     if (Firstime)  {
  164.         if ((Msqid=get_msg_queue()) == -1)  {
  165.             return(NULL);
  166.         }
  167.         Firstime=0;
  168.     }
  169.  
  170.     /* Get the user id */
  171.     uid=getuid();
  172.  
  173.     /* Receive a message.  The IPC_NOWAIT flag informs msgrcv()
  174.       * to return immediately if no message is on queue.  Without
  175.       * the IPC_NOWAIT flag this process would be put to sleep by 
  176.       * the kernel until a message of type uid is received.
  177.     */
  178.     if ((len=msgrcv(Msqid, &Msgbuf, BUFSIZ, uid, IPC_NOWAIT)) == -1)
  179.         return(NULL);
  180.  
  181.     /* Null terminate the message */
  182.     Msgbuf.mtext[len]=NULL;
  183.     return(Msgbuf.mtext);
  184. }
  185.         
  186. /*    GET_MSG_QUEUE FUNCTION
  187.  *
  188.  *    DESCRIPTION:    Gets and possibly creates a message
  189.  *                queue identifier via the msgget(2) 
  190.  *                system call.
  191.  *      
  192.  *    INPUT:        NONE
  193.  *    OUTPUT:        qid    Message queue ID
  194.  *                -1    Otherwise
  195. */
  196. get_msg_queue()
  197. {
  198.     int qid;
  199.  
  200.     /* Acquire a message queue.  
  201.       * The IPC_CREAT flag informs msgget() to create 
  202.       * the message queue with the permission 0666.
  203.       * The IPC_CREAT flags inform msgget() to create
  204.       * the message queue if it doesn't already exist.
  205.     */
  206.     if ((qid=msgget((key_t)KEY, 0666 | IPC_CREAT)) == -1)  {
  207.         return(-1);
  208.     }
  209.  
  210.     return(qid);
  211. }
  212.                 
  213.  
  214.